Skip to content

Fix IDE crash on @AfterClass #3027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

nicolasstucki
Copy link
Contributor

The TreeAccumulater was stuck in an infinite loop over the
synthetic constructor of java annotations. This could be reproduced
by opening the CompilationTests.scala in the IDE.

@nicolasstucki
Copy link
Contributor Author

This is a workarround for a infinite fold done on dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver. The fold loops arround the following trees:

Apply(Select(New(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),Target)]),<init>),List(NamedArg(value,JavaSeqLiteral(List(Literal(Constant(val ANNOTATION_TYPE))), TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),ElementType)]))))

Select(New(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),Target)]),<init>)

New(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),Target)])

Apply(Select(New(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),Target)]),<init>),List(NamedArg(value,JavaSeqLiteral(List(Literal(Constant(val ANNOTATION_TYPE))), TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,annotation)),ElementType)]))))

...
[error] Caused by: java.lang.StackOverflowError
[error] 	at dotty.tools.dotc.ast.Trees$Tree.symbol(Trees.scala:169)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1(InteractiveDriver.scala:187)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.tpd$TreeOps$.foreachSubTree$extension(tpd.scala:839)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup(InteractiveDriver.scala:193)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.immutable.List.foreach(List.scala:389)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1250)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1238)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1244)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.tpd$TreeOps$.foreachSubTree$extension(tpd.scala:839)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup(InteractiveDriver.scala:193)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.immutable.List.foreach(List.scala:389)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1250)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1238)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1244)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.tpd$TreeOps$.foreachSubTree$extension(tpd.scala:839)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup(InteractiveDriver.scala:193)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.immutable.List.foreach(List.scala:389)
[error] 	at dotty.tools.dotc.interactive.InteractiveDriver.cleanup$$anonfun$1(InteractiveDriver.scala:189)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:18)
[error] 	at scala.compat.java8.JProcedure1.apply(JProcedure1.java:10)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1250)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1238)
[error] 	at dotty.tools.dotc.ast.tpd$$anon$30.traverse(tpd.scala:837)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1330)
[error] 	at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1244)

@nicolasstucki nicolasstucki force-pushed the fix-ide-crash-on-java-annotations branch from 27032b5 to 80c57f2 Compare September 6, 2017 15:07
@nicolasstucki
Copy link
Contributor Author

@odersky, completely reimplemented the fix. I found the source of the issue and fixed it there.

@nicolasstucki nicolasstucki force-pushed the fix-ide-crash-on-java-annotations branch from 80c57f2 to dda2256 Compare September 6, 2017 15:41
@nicolasstucki nicolasstucki assigned smarter and unassigned odersky Sep 7, 2017
@nicolasstucki nicolasstucki removed the request for review from odersky September 7, 2017 08:49
@nicolasstucki
Copy link
Contributor Author

Resigned to @smarter as the code is it involves the IDE

@smarter
Copy link
Member

smarter commented Sep 12, 2017

Maybe add a comment explaining why this is necessary.

if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType
t.symbol.annotations.foreach(annot => cleanup(annot.tree))
private def cleanup(tree: tpd.Tree)(implicit ctx: Context): Unit = {
val cleanedTree = mutable.Set.empty[tpd.Tree]
Copy link
Member

@smarter smarter Sep 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would call this variable seen, this is the name we commonly use in the compiler for cycle detection.

The TreeAccumulator was stuck in an infinite loop over the
synthetic constructor of java annotations. This could be reproduced
by opening the CompilationTests.scala in the IDE.
@nicolasstucki nicolasstucki force-pushed the fix-ide-crash-on-java-annotations branch from fa2af08 to c552416 Compare September 13, 2017 08:11
cleanedTree += tree
tree.foreachSubTree { t =>
if (t.hasType) {
if (t.symbol.exists) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (t.hasType && t.symbol.exists) ?

@nicolasstucki
Copy link
Contributor Author

@allanrenucci, could you review the last commit and merge if ok.

@allanrenucci
Copy link
Contributor

As suggested by @smarter, I would add a comment explaining why this is necessary. Otherwise LGTM

@nicolasstucki nicolasstucki merged commit 660fab6 into scala:master Sep 19, 2017
@allanrenucci allanrenucci deleted the fix-ide-crash-on-java-annotations branch December 14, 2017 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants